package com.aaron.remoting.transport.socket;

import com.aaron.entity.RpcServiceProperties;
import com.aaron.exception.RpcException;
import com.aaron.extension.ExtensionLoader;
import com.aaron.registry.ServiceDiscovery;
import com.aaron.remoting.dto.RpcRequest;
import com.aaron.remoting.transport.RpcRequestTransport;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * 基于 Socket 传输 RpcRequest
 */
@AllArgsConstructor
@Slf4j
public class SocketRpcClient implements RpcRequestTransport {
    private final ServiceDiscovery serviceDiscovery;

    public SocketRpcClient() {
        this.serviceDiscovery = ExtensionLoader.getExtensionLoader(ServiceDiscovery.class).getExtension("zk");
    }

    @Override
    public Object sendRpcRequest(RpcRequest rpcRequest) {
        // build rpc service name by rpcRequest
//        String rpcServiceName = RpcServiceProperties.builder().serviceName(rpcRequest.getInterfaceName())
//                                                                .group(rpcRequest.getGroup())
//                                                                .version(rpcRequest.getVersion()).build()
//                                                                .toRpcServiceName();
        // 通过注册中心zk去 发现服务地址
        InetSocketAddress inetSocketAddress = serviceDiscovery.lookupService(rpcRequest);

        try (Socket socket = new Socket()) {
            socket.connect(inetSocketAddress);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
            // 向输出流中写入 请求对象
            objectOutputStream.writeObject(rpcRequest);

            // 从输入流中得到 服务端 返回的 消息对象
            ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
            return objectInputStream.readObject();
        } catch (IOException | ClassNotFoundException e) {
            throw new RpcException("调用服务失败:", e);
        }
    }
}
